package com.fhzn.boss.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fhzn.boss.entity.Resource;
import com.fhzn.boss.enums.Constants;
import com.fhzn.boss.enums.WebResponseEnum;
import com.fhzn.boss.mapper.ResourceMapper;
import com.fhzn.boss.service.OperatorLogService;
import com.fhzn.boss.service.ResourceService;
import com.fhzn.boss.web.converter.ResourceConverter;
import com.fhzn.boss.web.request.ResourceOpRequest;
import com.fhzn.boss.web.request.ResourceQueryRequest;
import com.fhzn.boss.web.vo.ResourceVO;
import com.fhzn.commons.toolkit.exception.BuzException;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * @author 老顾
 * @apiNote
 * @since 2023/12/20
 */
@Service
@RequiredArgsConstructor
public class ResourceServiceImpl extends ServiceImpl<ResourceMapper, Resource> implements ResourceService {

    private final ResourceMapper resourceMapper;
    private final OperatorLogService operatorLogService;

    @Override
    public Page<Resource> resourceWithPage(ResourceQueryRequest request) {
        request.checkParams();
        request.rewriteParams();
        request.getOffset();
        return resourceMapper.getResourcesByPage(request);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResourceVO addResource(ResourceOpRequest request) {
        request.checkBaseParams();
        request.checkAdd();
        Resource resource = request.addGenServiceParam();
        this.prepareWrite(resource);
        try {
            resourceMapper.insert(resource);
        } catch (Exception e) {
            throw new BuzException("新建资源失败，资源信息重复！");
        }
        operatorLogService.operatorLog(request.getHandler(), Constants.RESOURCE_SECTION, Constants.RESOURCE_ADD_METHOD, resource.getId(), null, resourceMapper.getResourceByCodeAndAppCode(request.getCode(), request.getAppCode()), Constants.APP_CODE);
        return ResourceConverter.fromResource(resource);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String updateResource(ResourceOpRequest request) {
        request.checkBaseParams();
        request.checkUpdate();
        Resource resourceBefore = resourceMapper.selectById(request.getId());
        if (resourceBefore == null) {
            throw new BuzException("资源不存在");
        }
        // 更新资源
        this.prepareWrite(request.genServiceParam());
        try {
            resourceMapper.updateById(request.genServiceParam());
        } catch (Exception e) {
            throw new BuzException("编辑资源信息失败，资源信息重复!");
        }
        // 记录操作日志
        operatorLogService.operatorLog(request.getHandler(), Constants.RESOURCE_SECTION, Constants.RESOURCE_UPDATE_METHOD, request.getId(), resourceBefore, resourceMapper.selectById(request.getId()), Constants.APP_CODE);
        return WebResponseEnum.SUCCESS.getMessage();
    }

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public void importResource(String data) throws JsonProcessingException {
        ObjectMapper objectMapper = new ObjectMapper();
        JsonNode rootNode = objectMapper.readTree(data);
        JsonNode resourcesNode = rootNode.get("resources");

        if (resourcesNode.isArray()) {
            for (JsonNode resourceNode : resourcesNode) {
                ResourceVO resourceVO = objectMapper.treeToValue(resourceNode, ResourceVO.class);
                Resource resource = ResourceConverter.fromResourceVO(resourceVO);

                // 检查数据库中是否已存在相同的记录
                Resource existingResource = resourceMapper.findByCodeAndAppCode(resource.getCode(), resource.getAppCode());
                if (existingResource != null) {
                    // 如果存在，更新记录
                    resource.setId(existingResource.getId());
                    resourceMapper.updateById(existingResource);
                } else {
                    // 如果不存在，插入新记录
                    resourceMapper.insert(resource);
                }
            }
        }
    }

    /**
     * 准备写入
     *
     * @param resource 资源
     */
    public void prepareWrite(Resource resource) {
        if (StringUtils.isBlank(resource.getParentCode())) {
            resource.setLevel(0);
        } else {
            Resource parent = resourceMapper.getResourceByCodeAndAppCode(resource.getParentCode(), resource.getAppCode());
            if (parent == null) {
                throw new BuzException("父资源不存在！");
            }
            resource.setLevel(parent.getLevel() == null ? 0 : parent.getLevel() + 1);
        }
    }

}
